package com.studentmanager;
import com.studentmanager.controller.TeacherController;
import com.studentmanager.domain.Teacher;
import com.studentmanager.service.TeacherService;
import com.studentmanager.util.PageBean;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

public class teachertest {

    @Autowired
    private MockMvc mockMvc;

    @Mock
    private TeacherService teacherService;

    @InjectMocks
    private TeacherController teacherController;

    private MockHttpSession session;

    @BeforeEach
    void setUp() {
        mockMvc = MockMvcBuilders.standaloneSetup(teacherController).build();
        session = new MockHttpSession();
    }

    @Test
    void testGetTeacherList() throws Exception {
        // Mocking the service method
        PageBean<Teacher> mockPageBean = new PageBean<>();
        mockPageBean.setDatas(Collections.singletonList(new Teacher()));
        mockPageBean.setTotalsize(1);

        when(teacherService.queryPage(any())).thenReturn(mockPageBean);

        // Call the controller and assert response
        mockMvc.perform(MockMvcRequestBuilders.post("/teacher/getTeacherList")
                        .param("page", "1")
                        .param("rows", "100")
                        .param("from", "combox")
                        .session(session))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.total").value(1))
                .andExpect(MockMvcResultMatchers.jsonPath("$.rows.length()").value(1));
    }

    @Test
    void testAddTeacher() throws Exception {
        // Prepare a mock teacher and file upload
        Teacher teacher = new Teacher();
        teacher.setClazzId(1);
        teacher.setName("Dr. John Doe");

        MockMultipartFile file = new MockMultipartFile("file", "profile.jpg", "image/jpeg", "image content".getBytes());

        when(teacherService.addTeacher(any(Teacher.class))).thenReturn(1);

        // Call the controller and assert response
        mockMvc.perform(MockMvcRequestBuilders.multipart("/teacher/addTeacher")
                        .file(file)
                        .param("teacher.name", "Dr. John Doe")
                        .param("teacher.clazzId", "1"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.success").value(true))
                .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("保存成功"));
    }

    @Test
    void testEditTeacher() throws Exception {
        // Prepare a mock teacher and file upload
        Teacher teacher = new Teacher();
        teacher.setId(1);
        teacher.setClazzId(1);
        teacher.setName("Dr. John Doe");

        MockMultipartFile file = new MockMultipartFile("file", "profile_updated.jpg", "image/jpeg", "image content".getBytes());

        when(teacherService.editTeacher(any(Teacher.class))).thenReturn(1);

        // Call the controller and assert response
        mockMvc.perform(MockMvcRequestBuilders.multipart("/teacher/editTeacher")
                        .file(file)
                        .param("teacher.id", "1")
                        .param("teacher.name", "Dr. John Doe Updated")
                        .param("teacher.clazzId", "1"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.success").value(true))
                .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("修改成功"));
    }

    @Test
    void testDeleteTeacher() throws Exception {
        // Mocking the service method
        List<Integer> ids = List.of(1, 2);
        when(teacherService.deleteTeacher(ids)).thenReturn(2);

        // Call the controller and assert response
        mockMvc.perform(MockMvcRequestBuilders.post("/teacher/deleteTeacher")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("{\"ids\":[1,2]}"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.success").value(true))
                .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("删除成功"));
    }

    @Test
    void testDeleteTeacherWithException() throws Exception {
        // Mocking the service method to throw an exception
        List<Integer> ids = List.of(1, 2);
        when(teacherService.deleteTeacher(ids)).thenThrow(new RuntimeException("删除失败"));

        // Call the controller and assert response
        mockMvc.perform(MockMvcRequestBuilders.post("/teacher/deleteTeacher")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("{\"ids\":[1,2]}"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.success").value(false))
                .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("删除失败"));
    }
}